0

我有一个目录,其中包含许多名称如下的文件:* _ * _ *** number (possibly)v2_ * 。* . * _1

我想删除除“number”和“_v2”(如果有的话)之外的所有内容,最好使用“cut”或类似的命令,因为我对 bash shell 脚本有些熟悉,但不熟悉 awk,例如

我尝试过使用各种剪切命令,例如:要删除前三个字段 + 分隔符“_”,我使用了这个:

for file in FIRSTSTRING_SECONDSTRING_THIRDSTRING_*; do echo mv $file $(echo $file | cut -c 26-); done

然后我想去掉最后两个字段。但我不知道该怎么做。

当然,如果所有文件名中间都有“数字”,那么我可以像这样去掉最后的字段:

for file in *_1; do echo mv $file $(echo $file | cut -d "_" -f 1); done

或者如果所有人都有“_number_v2_”,就这样:

for file in *_1; do echo mv $file $(echo $file | cut -d "_" -f 1,2); done

但是由于有两种文件名,我不知道该怎么做。我可以使用“rev”并删除前两个字段,然后再次使用“rev”,但 cut 不会删除,它会选择。是否有删除而不是选择的命令?

4

2 回答 2

1

您可以使用 awk:

$> cat file
BTDWQSDDFFSEWQA_NMDA_PRE_335_20030613.080620.437000_1
ABTDWQSDDFFSEWQA_NMDA_PRE_335_v2_20080129.160957.203000_1
ABTDWQSDDFFSEWQA_NMDA_PRE_336_20030603.170328.281000_1
ABTDWQSDDFFSEWQA_NMDA_PRE_336v2_20080129.160957.203000_1

$> awk -F_ '$5=="v2"{print $4, $5; next} {print $4}' OFS=_ file
335
335_v2
336
336v2

更新:: 使用上述模式重命名所有文件:

cd /somedir
while read l; do
    echo mv "$l" "$(awk -F_ '$5=="v2"{print $4, $5; next} {print $4}' OFS=_ <<< "$l")"
done < <(find . -type d -maxdepth 1 -name "*_*_*") 
于 2013-10-16T12:50:06.257 回答
0

这是一个不幸(或不)使用的解决方案awk

$ ls
FIRSTSTRING_SECONDSTRING_THIRDSTRING_12345
FIRSTSTRING_SECONDSTRING_THIRDSTRING_12345_UNWANTED
FIRSTSTRING_SECONDSTRING_THIRDSTRING_12345_v2

$ ls | tr '_' ' ' | awk '{ if ($5=="v2") print $4"_"$5; else print $4 }'
12345
12345
12345_v2

它是如何工作的:tr命令替换_为单个空格;然后这个小awk程序测试第 5 个字段是否是可选的v2。如果存在,则打印第 4 和第 5,并用下划线分隔它们;如果不是,则仅打印第 4 个字段。

要重命名文件:

for file in `ls`
do
  mv $file `echo $file | tr '_' ' ' | awk '{ if ($5=="v2") print $4"_"$5; else print $4 }'`;
done

或者,在一行中:

for file in `ls`; do mv $file `echo $file | tr '_' ' ' | awk '{ if ($5=="v2") print $4"_"$5; else print $4 }'`; done

但要小心具有相同名称的目标文件,就像在我的示例中一样:

$ ls
12345 # (one of the '12345' files was overwritten)
12345_v2

关于“请不要 awk”的请求,我想补充一点,您应该为正确的问题使用正确的工具。否则,就像用锤子敲螺丝一样。

于 2013-10-16T11:55:46.467 回答