Regex Bash脚本正则表达式…如何查找和替换所有匹配项?

Regex Bash脚本正则表达式…如何查找和替换所有匹配项?,regex,bash,shell,search,replace,Regex,Bash,Shell,Search,Replace,我正在编写一个bash脚本,逐行读取文件 该文件是一个.csv文件,其中包含许多日期,格式为DD/MM/YYYY,但我想将其更改为YYYY-MM-DD 我希望使用正则表达式匹配数据,并替换它,以便文件中的所有日期都正确格式化为YYYY-MM-DD 我相信这个正则表达式会匹配日期: ([0-9][0-9]?)/([0-9][0-9]?)/([0-9][0-9][0-9][0-9]) 但我不知道如何找到正则表达式匹配项并用新格式替换它们,或者在bash脚本中是否可以这样做。请帮忙 您可以使用sed

我正在编写一个bash脚本,逐行读取文件

该文件是一个.csv文件,其中包含许多日期,格式为DD/MM/YYYY,但我想将其更改为YYYY-MM-DD

我希望使用正则表达式匹配数据,并替换它,以便文件中的所有日期都正确格式化为YYYY-MM-DD

我相信这个正则表达式会匹配日期:

([0-9][0-9]?)/([0-9][0-9]?)/([0-9][0-9][0-9][0-9])

但我不知道如何找到正则表达式匹配项并用新格式替换它们,或者在bash脚本中是否可以这样做。请帮忙

您可以使用
sed

echo "11/12/2011" | sed -E 's/([0-9][0-9]?)\/([0-9][0-9]?)\/([0-9][0-9][0-9][0-9])/\3-\2-\1/'
使用sed尝试以下操作:

line='Today is 10/12/2010 and yesterday was 9/11/2010'
echo "$line" | sed -r 's#([0-9]{1,2})/([0-9]{1,2})/([0-9]{4})#\3-\2-\1#g'

OUTPUT:
Today is 2010-12-10 and yesterday was 2010-11-9
PS:在mac上使用
sed-E
而不是
sed-r

纯Bash

infile='data.csv'

while read line ; do
  if [[ $line =~ ^(.*),([0-9]{1,2})/([0-9]{1,2})/([0-9]{4}),(.*)$ ]] ; then
    echo "${BASH_REMATCH[1]},${BASH_REMATCH[4]}-${BASH_REMATCH[3]}-${BASH_REMATCH[2]},${BASH_REMATCH[5]}"
  else
    echo "$line"
  fi
done < "$infile"
提供以下输出:

xxxxxxxxx,2011-03-11,yyyyyyyyyyyyy
xxxxxxxxx,2011-04-10,yyyyyyyyyyyyy
xxxxxxxxx,2012-05-10,yyyyyyyyyyyyy
xxxxxxxxx,2011-06-10,yyyyyyyyyyyyy

我不想回显…我想将结果存储在一个新变量中

要做到这一点(我知道这对您的设置并不严格,但仍然适用于如何使用正则表达式):


注意:一些编辑建议交换
BASH_REMATCH[2]
BASH_REMATCH[3]
。我用
创建了一个文件,今天是2010年12月10日,昨天是2010年11月9日
行1024138次(文件大小~50MB),并将echo命令重定向到输出文件,运行脚本需要2分20秒才能完成。从上面的答案来看,类似的sed命令,
sed-r的#([0-9]{1,2})/([0-9]{1,2})/([0-9]{4})#\3-\2-\1#g'输入文件>输出文件
,只花了8秒。文件=(“$path”/*.jpg”“$path”/*.bmp”)是上面正确指定的字符串。此外,这并不是问题所要问的。如果你正确阅读我的帖子,你会发现我的回答不准确。谢谢你指出这一点。然而,尽管如此,这些数据还是无关紧要的。这个问题本质上是问如何将字符串中的文本替换为其他内容,我的代码对此进行了非常清楚和有效的演示,回答了这个问题。这个问题是关于使用bash进行基于正则表达式的替换。你是通过一个外部程序来完成的,而不是每个人现在都可能在他们的系统中拥有这个程序。为什么不改用
sed
?请参见Fritz G Mehner的回答。
xxxxxxxxx,2011-03-11,yyyyyyyyyyyyy
xxxxxxxxx,2011-04-10,yyyyyyyyyyyyy
xxxxxxxxx,2012-05-10,yyyyyyyyyyyyy
xxxxxxxxx,2011-06-10,yyyyyyyyyyyyy
path="/entertainment/Pictures"
files=(
  "$path"/*.jpg"
  "$path"/*.bmp"
)

for i in "${files[@]}"
do
  # replace jpg and bmp with png in prep for conversion
  new=$(echo "$i" | perl -pe "s/\.jpg|\.bmp/.png")

  # next is to perform the conversion
  ...
done