将文件与匹配的扩展名配对

发布于 2024-10-28 00:36:05 字数 232 浏览 2 评论 0原文

假设我有以下文件列表:

a.1
a.2
a.3
b.1
b.2

是否有一个 bash 单行代码可以找到一个不存在具有相同扩展名的“b”的“a”文件? (即a.3:不匹配
我确信我可以编写一个简短的 bash/perl 脚本来执行此操作。
但我想知道是否有任何“技巧”(当然,GNU 工具可供我使用;awk、sed、find ...)

Let's say I have this list of files:

a.1
a.2
a.3
b.1
b.2

Is there a bash one-liner that could find the one 'a' file for which there is no 'b' with the same extension? (i.e. a.3: no match)
I'm sure I could write a short bash/perl script to do this.
But I would like to know if there is any "trick" for this (of course, GNU tools are at my disposal; awk, sed, find ...)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

我的黑色迷你裙 2024-11-04 00:36:05

你可以试试这个:

ls -1 [ab].* | sort -t . -k 2 | uniq -u -s2

You could try this:

ls -1 [ab].* | sort -t . -k 2 | uniq -u -s2
浮光之海 2024-11-04 00:36:05

这是我的 bash 一句话,

for afile in a*; do bfile=${afile/a/b}; test -f $bfile || echo $afile; done

我喜欢上面的解决方案,因为它只使用 bash 而没有其他工具。然而,为了展示 Unix 工具的强大功能,下一个解决方案使用 4 个:ls、sed、sort 和 uniq:

ls [ab]* | sed 's/b/a/' | sort | uniq -u

Here is my bash one-liner

for afile in a*; do bfile=${afile/a/b}; test -f $bfile || echo $afile; done

I like the above solution since it only uses bash and no other tools. However, to showcase the power of Unix tools, the next solution uses 4: ls, sed, sort, and uniq:

ls [ab]* | sed 's/b/a/' | sort | uniq -u
老娘不死你永远是小三 2024-11-04 00:36:05

如果你可以使用 Perl:

perl -le 'for (<a*>) { /(.*)\.(.*)/; print "$1.$2" if !-e "b.$2"}'

If you can use Perl:

perl -le 'for (<a*>) { /(.*)\.(.*)/; print "$1.$2" if !-e "b.$2"}'
静若繁花 2024-11-04 00:36:05

bash 版本 4 有关联数组,因此您可以这样做:

declare -A a_files
while read -r filename; do
    ext="${filename##*.}"
    case "${filename%.*}" in 
        a) a_files[$ext]="$filename" ;;
        b) unset a_files[$ext] ;;
    esac
done < <(ls [ab].*)
echo "non-matched 'a' files: ${a_files[@]}"

或者,使用 awk:

ls [ab].* | awk -F. '
    $1 == "a" {a_files[$2] = $0} 
    $1 == "b" {delete a_files[$2]}
    END {for (ext in a_files) print a_files[ext]}
'

bash version 4 has associative arrays, so you can do this:

declare -A a_files
while read -r filename; do
    ext="${filename##*.}"
    case "${filename%.*}" in 
        a) a_files[$ext]="$filename" ;;
        b) unset a_files[$ext] ;;
    esac
done < <(ls [ab].*)
echo "non-matched 'a' files: ${a_files[@]}"

Or, with awk:

ls [ab].* | awk -F. '
    $1 == "a" {a_files[$2] = $0} 
    $1 == "b" {delete a_files[$2]}
    END {for (ext in a_files) print a_files[ext]}
'
倥絔 2024-11-04 00:36:05

红宝石(1.9+)

$ ruby -e 'Dir["a.*"].each{|x|puts x if not File.exist? "b."+x.scan(/a\.(\d+)/)[0][0]}'

Ruby(1.9+)

$ ruby -e 'Dir["a.*"].each{|x|puts x if not File.exist? "b."+x.scan(/a\.(\d+)/)[0][0]}'
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文