我是正则表达的新手。需要帮助来阅读unix
系统中的文件。我想在ls
命令上应用正则表达式。
我有以下文件:
DLERMS0800的 170816 1708209683.csv.gz
DLERMS1300的 170816 1330170816.csv.gz
DLERMS13001708171330170816.csv.gz
并且想要提取在第11记录到第16位之间具有170816的文件。
我尝试使用下面的命令ls *170816*.gz
。但是我得到3个文件名而不是2个。我只想要前两个文件名而不是全部3.你能不能帮忙。
另外我想在这里添加我的第三个文件名已经在末尾包含170816 DLERMS13001708171330 170816
。csv.gz。我想在我的ls
命令输出中避免这种情况。
答案 0 :(得分:3)
仅使用bash
参数扩展,
for file in *.csv.gz; do
[ -e "$file" ] || continue
[ "${file:10:6}" == "170816" ] && printf "%s\n" "$file"
done
${PARAMETER:OFFSET:LENGTH}
这个只能扩展参数值的一部分,给定一个开始的位置,也许是一个长度。如果省略
LENGTH
,则参数将扩展到字符串的末尾。如果LENGTH
为负数,则将其作为字符串的第二个偏移量,从字符串的末尾开始计算
根据下面的评论,显然OP希望将目标文件复制到备用路径,在这种情况下,printf()
应该用cp
替换为必要的参数
[ "${file:10:6}" == "170816" ] && cp -- "$file" path/to/destination
答案 1 :(得分:2)
首先,注意不要将正则表达式与shell glob模式混淆(这就是你想要的)。
你的全球可能是:
ls
匹配10个未知字符,后跟您指定的序列。
根据您的下一步,您可能根本不需要使用for file in ??????????170816*.gz; do
something_with "$file"
done
,例如,您可以像这样循环遍历这些文件:
echo ??????????170816*.gz
printf '%s\n' ??????????170816*.gz
或使用以下方法之一输出匹配的文件:
nullglob
如果有可能没有文件匹配,那么您可以考虑启用shopt -s nullglob
(使用{{1}}),在这种情况下会扩展为空。
答案 2 :(得分:2)
如果您想使用globbing,则与使用正则表达式不同。
在您的示例中,您可以使用“?”作为匹配单个字符的占位符:
因此,要实现您想要的输出,请使用以下模式的ls -
ls ??????????170816*
答案 3 :(得分:1)
您希望经常使用通配符(不是正则表达式)“任何单个字母”?
。
ls DLERMS????170816*.csv.gz
对于这个简单的用例,正则表达式更灵活/更强大并且过度使用 但据我所知,ls不支持它们,因此您必须通过其他bash工具来识别文件,以防您需要实际使用正则表达式。
我还反映了我认为你文件名的另一个常见内容,即开头的DLERMS,如果不常见,也可以用?
替换这些字母。
答案 4 :(得分:1)
试试这个:
ls ??????????170816*
答案 5 :(得分:0)
我认为您不能直接使用ls
的正则表达式,但使用egrep
时,它可以正常使用。
ls * | egrep "DLERMS[0-9]{4}170816[0-9]{10}.csv.gz"
[0-9] {4} - 任意数字,四次。 [0-9] {10} - 任意数字,十次。
也可以代替" egrep"命令" grep -E",-E选项允许特殊的正则表达式,如" [{|"无需逃避他们" \"。
答案 6 :(得分:0)
使用find和regex的解决方案
find . -regextype egrep -regex "^.{12}170816.*\.gz"
找到读:./xxxxxxxxxxxxx和。{12}表示前十二个,所以170816表示第13记录到第18个