我知道以前曾经问过类似的事情,但是我还没有能够真正地从已发布的内容中做出手脚。
我在文件名中的某个位置有一大堆文件,其中包含格式为YYYYMMDD的日期。幸运的是,这是所有文件名中唯一的8位数字符串!
稍后我需要将日期写入另一个文件,但这应该没问题。我首先努力将日期提取到变量中......
我知道我可以用grep获取它:
for d in $( ls *.csv | grep -Po "\d{8}"; do
echo $d done
但是,由于我想在迭代它们时将完整的文件名转换为变量,所以现在不能选择。
我尝试使用sed,但我不认为我知道如何使用它:
for f in $( ls *.csv ); do
d=$( $f | sed -e 's/^.*\(\d{8}\).*$')
echo $d
done
感谢您指出我正确的方向!
答案 0 :(得分:2)
像这样循环你的csv文件(不要解析ls
):
for f in *.csv; do
echo "$f"
d=$(echo "$f" | grep -oE '[0-9]{8}')
done
我在扩展模式(-E
)中使用了grep,但perl模式同样有效。
如果您使用bash进行了标记,则可以d=$(grep -oE '[0-9]{8}' <<<"$f"
代替,如果您愿意的话。您还可以使用内置的正则表达式支持,这种支持稍微冗长,但可以省去调用外部工具:
re='[0-9]{8}'
[[ $f =~ $re ]] && d="${BASH_REMATCH[0]}"
数组BASH_REMATCH
包含与正则表达式的匹配项。如果匹配,我们会将其分配给d
。
答案 1 :(得分:1)
#!/bin/bash
# ^-- important: bash, not not /bin/sh
for f in *.csv; do # Don't use ls for iterating over filenames
[[ $f =~ [[:digit:]]{8} ]] && { # native built-in regex matching
number=${BASH_REMATCH[0]} # ...refer to the matched content...
echo "Found $number in filename $f" # ...and emit output.
}
done