使用多个分隔符分割字符串

使用多个分隔符分割字符串

我有一个包含以下字符串的文本文件,我想将其转换为 CSV 文件。

我想分割下面的字符串:

location = /example/url/newsite/redirect {return 301 https://example.com/fr;}

...到如下值:

/example/url/newsite/redirect,301,https://example.com/fr

目前我正在使用以下命令

awk '{gsub(/;}/,"",$6); if ($1 == location) print $3","$6 }' redirections/*.redirections >> redirect-csv/redirect.csv

理想情况下,我们不必指定文件名。它应该获取redirections/中的所有*.redirections文件并进行1对1映射以在redirect-csv中生成文件。

redirections/
site1.redirections
site2.redirections

Run the magic command.

redirect-csv/
site1.csv
site2.csv

答案1

解决这种问题的最佳方法是使用正则表达式将字符串与模式进行匹配并提取相关部分。

echo "location = /example/url/newsite/redirect {return 301 https://example.com/fr;}" |
  sed -n 's/^location = \(.*\) {return \(3[[:digit:]]\{2\}\) \(.*\);}$/\1,\2,\3/p'

给出

/example/url/newsite/redirect,301,https://example.com/fr

或者,如果字段可能包含 CSV 格式中的特殊字符(例如,, "):

perl -MText::CSV -lne '
  BEGIN{$c = Text::CSV->new}
  if (/^location = (.*) \{return (3\d\d) (.*);\}$/) {
    $c->print(STDOUT, [$1, $2, $3])
  }'

答案2

更改后,这是基于第一个解决方案的解决方案

for file in redirections/*.redirection; do fname=$(basename $file); awk '{gsub(/;}/,"",$6); print $3" & "$5" & "$6 }' $file > redirect-csv/${fname/.redirection/.csv}; done

答案3

嗯,如果这一行始终遵循相同的模型,则用 awk 一行?

echo "location = /example/url/newsite/redirect {return 301 https://example.com/fr;}" | awk '{gsub(/;}/,"",$6); print $3" & "$5" & "$6 }'

将其重定向到“myfile.csv”中

awk '{gsub(/;}/,"",$6); print $3" & "$5" & "$6 }' list.txt >> myfile.csv

其中 list.txt 包含您的行

答案4

  1. 一个错误——这段代码是OP问题的缩写:

    awk '...stuff...' r/*.red >> r-c/red.csv
    

    ...将输入许多文件,更改它们,然后输出一个超长文件 红色.csv文件。 重定向>>行为相当像cat foo/* > bar/baz.

  2. 使用相同的缩写来避免自动换行,使用 withbasename 和 xargs,生成cp命令以在更改文件名称时将r/文件复制到其中r-c/,并使用以下命令就地编辑这些新文件GNU sed:

    basename -a -s r/*.red | xargs -L 1 -I {}   cp  r/{}.red  r-c/{}.csv
    sed -i 's/^[^=]*= \|\;}$//g;s/ [^ ]* /,/;s/ /,/'  r-c/*.csv
    

相关内容