【问题标题】:Run command for every line?为每一行运行命令?
【发布时间】:2018-04-03 06:35:32
【问题描述】:

我有一堆 1255-138279.trans.txt 文件,其中包含如下行:

1255-138279-0006 THE SHAPE WENT SLOWLY ALONG BUT WITHOUT MUCH EXERTION FOR THE SNOW THOUGH SUDDEN WAS NOT AS YET MORE THAN TWO INCHES DEEP
1255-138279-0007 AT THIS TIME SOME WORDS WERE SPOKEN ALOUD ONE
1255-138279-0008 TWO THREE
1255-138279-0009 FOUR FIVE
1255-138279-0010 BETWEEN EACH UTTERANCE THE LITTLE SHAPE ADVANCED ABOUT HALF A DOZEN YARDS
1255-138279-0011 HERE THE SPOT STOPPED AND DWINDLED SMALLER
1255-138279-0012 THEN A MORSEL OF SNOW FLEW ACROSS THE RIVER TOWARDS THE FIFTH WINDOW
1255-138279-0013 THE RIVER WOULD HAVE BEEN SEEN BY DAY TO BE OF THAT DEEP SMOOTH SORT WHICH RACES MIDDLE AND SIDES WITH THE SAME GLIDING PRECISION ANY IRREGULARITIES OF SPEED BEING IMMEDIATELY CORRECTED BY A SMALL WHIRLPOOL
1255-138279-0014 THE WINDOW WAS STRUCK AGAIN IN THE SAME MANNER
1255-138279-0015 THEN A NOISE WAS HEARD APPARENTLY PRODUCED BY THE OPENING OF THE WINDOW
1255-138279-0016 SAID THE BLURRED SPOT IN THE SNOW TREMULOUSLY
1255-138279-0017 I ASKED WHICH WAS YOUR WINDOW FORGIVE ME
1255-138279-0018 WELL I SAID THAT YOU MIGHT
1255-138279-0019 O MUST I IT IS WHEN SHALL WE BE MARRIED FRANK
1255-138279-0020 I HAVE MONEY
1255-138279-0021 AND WE LIVE IN TWO PARISHES DO WE WHAT THEN
1255-138279-0022 IF I SAID SO OF COURSE I WILL
1255-138279-0023 THE FACT IS I FORGOT TO ASK
1255-138279-0024 GOOD NIGHT FRANK GOOD NIGHT

对于每一行,我想创建一个新文件,命名为1255-138279-0008.txt(或行首的任何代码),并包含该行的其余部分(在本例中为TWO THREE)。

【问题讨论】:

  • 当第一个字段不唯一时你想要什么?或者你知道这不会发生吗?
  • @WalterA 这不会发生。不过,覆盖会很好,感谢您注意到这一点并指出。

标签: regex string bash macos terminal


【解决方案1】:

试试这个:

$ awk '{v=$1; $1=""; print $0 > "path/to/dir/"v".txt"}' file.txt
$ ls -1 path/to/dir/*.txt

【讨论】:

  • 我得到一个错误 awk:源代码行 1 上下文的语法错误是 {v=$1; $1=""; print $0 > >>> v".txt"
  • 也许可以明确地尝试 gawk
  • 如何更改输出文件路径?在子目录中
【解决方案2】:

我更喜欢分两步执行此操作。 首先,使用sedawk生成一个shell脚本:

sed "s/^\s*\(\S\+\)\s\+\(.*\)$/echo '\2' > '\1.txt'/g" input.txt > output.sh

或者使用符合 POSIX 的正则表达式(没有 GNU 扩展):

sed "s/^[[:space:]]*\([^[:space:]]\+\)[[:space:]]\+\(.*\)$/echo '\2' > '\1.txt'/g" input.txt > output.sh

或使用 ERE:

sed -E "s/^[[:space:]]*([^[:space:]]+)[[:space:]]+(.*)$/echo '\2' > '\1.txt'/g" input.txt > output.sh

输出:

...
echo 'TWO THREE' > '1255-138279-0008.txt'
echo 'FOUR FIVE' > '1255-138279-0009.txt'
...

然后执行该脚本以生成文件。

. output.sh

【讨论】:

  • 这个对我根本不起作用。可能是因为我是macOS?
  • @WalterA 非常优雅,但在我完全确信sed 命令足够可靠以涵盖所有可能的输入文件之前,我不会去那里。中间文件有助于分析偶发问题并微调正则表达式。
  • @theonlygusti 很抱歉; \S\s 是 GNU 扩展。请分别替换为它们的 POSIX 等效项 [^[:space:]][[:space:]]
【解决方案3】:

shell 中的这个简单的while 循环可以完成这项工作:

while read -r id line; do
   echo "$line" >> "$id.txt"
done < file

【讨论】:

    猜你喜欢
    • 2012-12-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-02
    • 2014-08-21
    • 2012-01-18
    • 2021-10-29
    相关资源
    最近更新 更多