假设我有以下文件。
ABC_DEF_G-1_P-249_8.CSV
我想在下面剪切。
ABC_DEF_G-1_P-249_
我使用这个awk命令来执行以下操作。
ls -lrt | grep -i .CSV | tail -1 | awk -F ' ' '{print $8}' | cut -c 1-18
问题,如果数字1正在增长,如何使子字符串变为动态
例如下面......
ABC_DEF_G-1_P-249_
....
ABC_DEF_G-10_P-249_
ABC_DEF_G-11_P-249_
...
ABC_DEF_G-1000_P-249_
答案 0 :(得分:3)
要显示所有.CSV
的文件名,而不是最后一个下划线后的所有内容,您可以这样做:
for fname in *.CSV; do echo "${fname%_*}_"; done
这将删除其后的最后一个下划线和evertyhing(${fname%_*}
),然后再次附加下划线。例如,您可以将其分配给另一个变量。
对于
的示例文件列表ABC_DEF_G-1_P-249_9.CSV
ABC_DEF_G-10_P-249_8.CSV
ABC_DEF_G-1000_P-249_4.CSV
ABC_DEF_G-11_P-249_7.CSV
ABC_DEF_G-11_P-249_7.txt
这导致
$ for fname in *.CSV; do echo "${fname%_*}_"; done
ABC_DEF_G-1_P-249_
ABC_DEF_G-10_P-249_
ABC_DEF_G-1000_P-249_
ABC_DEF_G-11_P-249_
答案 1 :(得分:1)
你可以用ls和grep
来做到这一点 ls -1rt | grep -oP ".*(?=_\d{1,}\.CSV)"
如果您担心ls -1的输出,如评论中所述,您也可以使用find
find -type f -printf "%f\n" | grep -oP ".*(?=_\d{1,}\.CSV)"
输出:
ABC_DEF_G-1_P-249
ABC_DEF_G-1000_P-249_
这假设您需要除_number.CSV之外的所有内容,如果它需要不区分大小写,那么您可以将-i
标记为grep。 \d{1,}
允许_和.CSV之间的数字从一个到多个数字增长。同样这样做你不必担心你的例子中的数字1是否增加:
ABC_DEF_G-的 1 强> _P-249
答案 2 :(得分:0)
你不应该解析ls
。也许你正在寻找这样的东西:
base=$(printf "%s\n" * | grep -i .CSV | tail -1 | awk -F ' ' '{print $8}' | cut -c 1-18)
然而,那个' sa useless use of grep
你想摆脱那里 - Awk做的所有事情grep
都做了,所有事情tail
也做了,实际上,一切cut
也可以。不过,使用更好的通配符也可以避免使用grep
:
base=$(printf "%s\n" *.[Cc][Ss][Vv] | awk 'END { print substr($8, 1, 18) }')
在shell本身,你可以做很多相同的事情,根本没有外部进程。但是,提出合适的解决方法可能需要更好地了解您要完成的任务。