【问题标题】:use regex to specify output filename使用正则表达式指定输出文件名
【发布时间】:2018-06-06 02:15:55
【问题描述】:

我有一个包含许多文件的文件夹,我只需要一些列,所以我尝试了这个来提取我需要的内容:

mkdir ./raw_data/selection

doit() {
    csvfix read_dsv -f 1,3,7 -s \; $1 > $1 | sed 's/raw_data/raw_data\/selection/'
}
export -f doit
Files_To_Parse=`ls ./raw_data/*csv`
parallel doit ::: $Files_To_Parse

这不起作用。

但如果我这样做:

cd ./raw_data
doit() {
    csvfix read_dsv -f 1,3,7 -s \; $1 > selection/$1
}
export -f doit
Files_To_Parse=`ls -1 *csv`
parallel doit ::: $Files_To_Parse

它可以工作,但我希望能够从这个项目的顶层文件夹运行它(即将它放在一个名为 brief_csv.sh 的文件中并从 IDE 调用它)

【问题讨论】:

  • 这是您第一次尝试 ls 命令中没有“-1”选项的错字吗?我希望这是必要的。对于您的主要问题,如果这是 Bash,您是否尝试过“$1 > ./raw_data/selection/${1:9}”?否则,可能是“$1 > $(echo $1 | sed 's/raw_data/raw_data\/selection/')”?
  • ls 知道它何时写入管道,并自动启用 -1 行为。仅当您想在交互式会话中查看输出的样子时,才真正需要该选项。
  • 无论如何,不​​要在脚本中使用lsmywiki.wooledge.org/ParsingLs 正确的做法是parallel doit ::: *csv

标签: regex shell sh


【解决方案1】:

如果您使用 Bash,您可以:

for f in raw_data/*.csv
do 
    csvfix ... "$f" > raw_data/selection/"${f##*/}"
done

此外,您可以使用 cut 代替 csvfix 提取列:

$ cut -d \; -f 1,3,7 $f ...

【讨论】:

    【解决方案2】:

    我不知道你使用的命令,但是这一行:

    csvfix read_dsv -f 1,3,7 -s \; $1 > $1 | sed ...

    将输出重定向到您正在阅读的同一文件中;这是行不通的。实际上,您说您修改后的代码可以正常工作。您可以使用临时文件来存储中间结果,不要害怕使用其中的许多:调试会更容易(您可以看到中间段落)并且系统不会受到影响。 /tmp 是放置这些中间文件的好地方。

    使用 csvfix 做第一步,并在 /tmp/my-csvfix-intermediate 中重定向;然后使用 sed 读取 /tmp/my-csvfix-intermediate,并写入 /tmp/my-grep-intermediate。在最后一段之后,您可以获取最后的中间结果并覆盖原始文件,也许在备份之后。您可以将文件移动到您需要的任何地方,我认为从 IDE 运行脚本没有任何问题 - 只需根据需要使用尽可能多的段落。

    调试时避免并行化,当脚本可以工作时,可以添加并行化。

    当两个或多个并行进程尝试写入同一个文件(/tmp/my-...-intermediate)时,您将遇到另一个问题。为了克服这个问题,您需要为每个进程使用不同的文件。 bash 变量“$$”来帮忙,使用文件名如“/tmp/my-$$-blablabla”,$$ 将替换为进程的PID,并行进程不能有相同的PID .

    希望对你有帮助,问候。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-09-27
      • 1970-01-01
      • 2023-04-03
      • 2011-09-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-08-10
      相关资源
      最近更新 更多