子外壳结果与预期不同

时间:2019-09-02 12:33:40

标签: bash shell sed

我正在设置一个列表,以删除旧文件并保留最新的5个版本,其中的文件数量将从列表中删除。

GNU bash,v4.3.48

文件:测试

        "npm/usagecontrol-ui/usagecontrol-ui-0b7c6c7f-17.tgz", 
        "npm/usagecontrol-ui/usagecontrol-ui-0c77b6bf-15.tgz", 
        "npm/usagecontrol-ui/usagecontrol-ui-191743df-10.tgz", 
        "npm/usagecontrol-ui/usagecontrol-ui-2fa8b89d-14.tgz", 
        "npm/usagecontrol-ui/usagecontrol-ui-4fdca5ca-18.tgz", 
        "npm/usagecontrol-ui/usagecontrol-ui-5bd9abf4-7.tgz", 
        "npm/usagecontrol-ui/usagecontrol-ui-6a6743ee-11.tgz", 
        "npm/usagecontrol-ui/usagecontrol-ui-9d47b9a5-16.tgz", 
        "npm/usagecontrol-ui/usagecontrol-ui-bc77eec4-19.tgz", 
        "npm/usagecontrol-ui/usagecontrol-ui-cfd66059-12.tgz", 
        "npm/usagecontrol-ui/usagecontrol-ui-d136baa3-13.tgz", 
        "npm/usagecontrol-ui/usagecontrol-ui-ffa49b6b-9.tgz"

测试子shell:

$ cat test | sed -r 's/.*-([0-9]+\.tgz).*/\1/g' | sort -n | tail -n 5 | xargs| sed 's/ /|/g;s/^/\"/g;s/$/\"/g'

结果(要保存的文件):

"15.tgz|16.tgz|17.tgz|18.tgz|19.tgz"

忽略5个文件的命令。

cat teste | grep -vE $(cat teste | sed -r 's/.*-([0-9]+\.tgz).*/\1/g' | sort -n | tail -n 5 | xargs| sed 's/ /|/g;s/^/\"/g;s/$/\"/g')

结果(要删除的文件):

        "npm/usagecontrol-ui/usagecontrol-ui-0c77b6bf-15.tgz", 
        "npm/usagecontrol-ui/usagecontrol-ui-191743df-10.tgz", 
        "npm/usagecontrol-ui/usagecontrol-ui-2fa8b89d-14.tgz", 
        "npm/usagecontrol-ui/usagecontrol-ui-5bd9abf4-7.tgz", 
        "npm/usagecontrol-ui/usagecontrol-ui-6a6743ee-11.tgz", 
        "npm/usagecontrol-ui/usagecontrol-ui-cfd66059-12.tgz", 
        "npm/usagecontrol-ui/usagecontrol-ui-d136baa3-13.tgz",

grep -vE选择15.tgz进行删除。但我希望保留15.tgz。像16.tgz,17.tgz,18.tgz和19.tgz。

1 个答案:

答案 0 :(得分:1)

不要分两次通过,只需一个就足够了。您不需要“首先提取要保留的索引”,然后“将要保留的索引与所有索引的列表合并,并删除不相交的组”。只需在流通过时对其进行操作,即可同时完成这两个操作。

以下脚本中带有代码注释:

cat <<EOF |
        "npm/usagecontrol-ui/usagecontrol-ui-0b7c6c7f-17.tgz",
        "npm/usagecontrol-ui/usagecontrol-ui-0c77b6bf-15.tgz",
        "npm/usagecontrol-ui/usagecontrol-ui-191743df-10.tgz",
        "npm/usagecontrol-ui/usagecontrol-ui-2fa8b89d-14.tgz",
        "npm/usagecontrol-ui/usagecontrol-ui-4fdca5ca-18.tgz",
        "npm/usagecontrol-ui/usagecontrol-ui-5bd9abf4-7.tgz",
        "npm/usagecontrol-ui/usagecontrol-ui-6a6743ee-11.tgz",
        "npm/usagecontrol-ui/usagecontrol-ui-9d47b9a5-16.tgz",
        "npm/usagecontrol-ui/usagecontrol-ui-bc77eec4-19.tgz",
        "npm/usagecontrol-ui/usagecontrol-ui-cfd66059-12.tgz",
        "npm/usagecontrol-ui/usagecontrol-ui-d136baa3-13.tgz",
        "npm/usagecontrol-ui/usagecontrol-ui-ffa49b6b-9.tgz"
EOF
# extract the strings inside "
sed -r 's/[[:space:]]*"([^"]*).*/\1/' |
# sort using the numbers
# sort using `-` as the separator for fields and sort using 5th field
sort -t- -n -k5,5 |
# remove 5 newest files
head -n -5  |
# remove the rest of the files
xargs echo rm

输出:

rm npm/usagecontrol-ui/usagecontrol-ui-5bd9abf4-7.tgz npm/usagecontrol-ui/usagecontrol-ui-ffa49b6b-9.tgz npm/usagecontrol-ui/usagecontrol-ui-191743df-10.tgz npm/usagecontrol-ui/usagecontrol-ui-6a6743ee-11.tgz npm/usagecontrol-ui/usagecontrol-ui-cfd66059-12.tgz npm/usagecontrol-ui/usagecontrol-ui-d136baa3-13.tgz npm/usagecontrol-ui/usagecontrol-ui-2fa8b89d-14.tgz

如果不确定文件名中的数字-,最好的方法是先提取[0-9]*.tgz前面的数字,然后将它们放在文件名中。然后对列表进行排序并删除索引。

cat <<EOF |
        "npm/usagecontrol-ui/usagecontrol-ui-0b7c6c7f-17.tgz",
        "npm/usagecontrol-ui/usagecontrol-ui-0c77b6bf-15.tgz",
        "npm/usagecontrol-ui/usagecontrol-ui-191743df-10.tgz",
        "npm/usagecontrol-ui/usagecontrol-ui-2fa8b89d-14.tgz",
        "npm/usagecontrol-ui/usagecontrol-ui-4fdca5ca-18.tgz",
        "npm/usagecontrol-ui/usagecontrol-ui-5bd9abf4-7.tgz",
        "npm/usagecontrol-ui/usagecontrol-ui-6a6743ee-11.tgz",
        "npm/usagecontrol-ui/usagecontrol-ui-9d47b9a5-16.tgz",
        "npm/usagecontrol-ui/usagecontrol-ui-bc77eec4-19.tgz",
        "npm/usagecontrol-ui/usagecontrol-ui-cfd66059-12.tgz",
        "npm/usagecontrol-ui/usagecontrol-ui-d136baa3-13.tgz",
        "npm/usagecontrol-ui/usagecontrol-ui-ffa49b6b-9.tgz"
EOF
# extract the strings inside "
sed -r 's/[[:space:]]*"([^"]*).*/\1/' |
# extract the index in front of .thz and put it in front of the line
sed -r 's/^.*-([0-9]*)\.tgz$/\1 &/' |
# sort using the extracted numbers
sort -n -k1,1 |
# remove the indexes
cut -d' ' -f2- |
# remove 5 newest files
head -n -5  
# remove the rest of the files
xargs echo rm

注意:

  • s/ /|/g;s/^/\"/g;s/$/\"/g-在单引号内转义双引号不会执行任何操作。与s/ /|/g;s/^/"/g;s/$/"/g相同。
  • | xargs|是没有用的,它是一个空操作。它几乎等于| cat |