将txt转换为列文件

时间:2019-01-13 20:31:15

标签: bash awk

我需要将test.txt文件转换为带列文件。

如果每个关键字后的行数相同但在此示例中不同,我知道如何用awk进行转换。

awk 'NR % 5 {printf "%s ", $0; next}1' test.txt 

如果行数相同,则为代码,但此行不适用于此输入文件。

要转换吗?请告知。

test.txt

"abc"
4
21
22
25
"standard"
1
"test"
4
5
10
11
12

预期输出:

"abc" 4 21 22 25
"standard" 1 
"test" 4 5 10 11 12

5 个答案:

答案 0 :(得分:2)

$ awk '{printf "%s%s", (/^"/ ? ors : OFS), $0; ors=ORS} END{print ""}' file
"abc" 4 21 22 25
"standard" 1
"test" 4 5 10 11 12

答案 1 :(得分:0)

有点魔术,但在这种情况下有效:

sed -z 's/\n"/\n\x01"/g' |
tr '\n' ' ' |
tr $'\x01' '\n'
  1. 每个“标头”开头都是" ... "之间的字符串。所以:
  2. 使用sed,在文件中的所有位置,在换行符和"之间放置了一个除法符(我选择了十六进制的0x01)。请注意,-z是gnu扩展名。
  3. 然后我将所有换行符替换为一个空格。
  4. 然后我将所有0x01个字节替换为换行符。

此方法有点棘手,但是很简单,并且在标头在行首以某些字符开头的情况下可以使用。

可通过tutorialspoint获得实时版本。

例如,使用sed而不使用gnu扩展名即可获得

sed '2,$s/^"/\x01"/'

即。如果行以"开头则大于第二行,然后在行的开头添加0x01字节。

答案 2 :(得分:0)

POSIX awk:

checked

或使用$ awk '/^"/{if (s) print s; s=$0; next} {s=s OFS $0} END{print s}' file "abc" 4 21 22 25 "standard" 1 "test" 4 5 10 11 12

perl

如果您的字段中没有空格,则可以使用简单的$ perl -0777 -lnE 'for (/^"[^"]+"\R(?:[\s\S]+?)(?=^"|\z)/mg) {tr /\n/ /; say} ' file tr管道:

sed

或GNU sed:

$ cat file | tr '\n' ' ' | sed -E 's/ ("[^"]*")/\
\1/g' 

答案 3 :(得分:0)

使用GNU awk

$ awk -v RS='\n"' '{$1=$1; printf "%s", rt $0; rt=RT}' file
"abc" 4 21 22 25
"standard" 1
"test" 4 5 10 11 12

答案 4 :(得分:0)

尽管建议使用getDollarValueawk解决方案,但由于该问题也被标记为sed,因此您可以通过简单的读取循环和标志变量来控制所有操作第一次迭代的换行输出。本质上,您正在读取每一行,并使用字符串索引 parameterexpandment 来测试第一个字符是否为非数字,并且在第一个迭代中仅输出字符串,对于所有其他迭代,则输出以bash开头的字符串。如果该行以数字开头,则只需在其前面输出一个空格即可。

例如:

'\n'

使用/输出示例

#!/bin/bash

declare -i n=0          ## simple flag to omit '\n' on first string output

while read -r line; do  ## read each line
    [[ ${line:0:1} =~ [^0-9] ]] && {    ## begins with non-digit
        ## 1st iteration, just output $line, rest output '\n$line'
        ((n == 0)) && printf "%s" "$line" || printf "\n%s" "$line"
    } || printf " %s" "$line"   ## begins with digit - output " $line"
    n=1     ## set flag
done < "$1"
echo ""     ## tidy up with newline

虽然$ bash fmtlines test.txt "abc" 4 21 22 25 "standard" 1 "test" 4 5 10 11 12 awk通常会更快(作为一般规则),但这里只不过是sed循环和一些条件和参数扩展而已,它是本机bash解决方案比较起来还不错。

仔细研究一下,如果您有任何疑问,请告诉我。

相关问题