如何在使用 grep 获得的每一行的末尾附加一个值
How to append a value at the end of each line obtained with grep
我有一些 CSV 文件,我想用 grep(或终端中的其他一些函数)解析这些文件以提取一些信息。
它们的形式是:
* Comment 1
* Comment line 2 explaining what the following numbers mean
1000000 ; 3208105 ; 0.18 ; 0.45 ; 0.00015 ; 0.1485 ; 0.03 ; 1 ; 1 ; 5 ; 477003 ;
* Comment 3
* Comment 4 explaining the meaning of the following lines
* Comment 5
0; 706520; p; 30.4983
1; 20859; p; 57.8
2; 192814; p; 111.842
3; 344542; p; 130.543
4; 54605; p; 131.598
5; 64746; d; 140.898
6; 442082; p; 214.11
7; 546701; p; 249.167
8; 298394; p; 305.034
9; 81188; p; 305.034
.......
在每个文件中最多只能有一行第三个字段等于 d
而不是 p
。所以要么有一行包含 d
要么有 none.
我有很多这样的文件,我想做的是从每个文件中提取包含字母 d
的行(如果存在),并在该行之后附加第一个参数的最后一个参数非注释行,在此示例中为 47703
.
到目前为止,我设法分别提取了我需要的行。
有了这个,我可以从我拥有的每个文件中提取包含 d
的每一行:
grep -h -E ' d;' *.csv > output.csv
这样我就可以从文件中准确提取数字 47703
,例如示例中的文件:
grep -v -e "^*" -e " p; " -e " d; " example_file.csv | cut -d \; -f 11
但是我不知道怎么把这两个放在一起。
我想从开头的示例中获得的最终输出是这样的一行:
5; 64746; d; 140.898; 47703
我想为当前目录中的每个 CSV 文件添加这样一行。
有办法吗?
我使用 for 循环来循环所有 .csv 文件,并将 greps 的返回值分配给变量,这些变量在每个循环结束时连接回显:
for f in *.csv ; do value=`grep -v -e "^*" -e " p; " -e " d; " -e '^\s*$' "$f" | cut -d \; -f 11` ; line=`grep -h -E ' d;' "$f" ; echo "$line;$value" ; done
编辑:(我还在第一个 grep 中添加了 -e '^\s*$'
,它在第一个未注释的行上获取包含值的行。之前,它匹配空行)
这只会回显您想要的 5; 64746; d; 140.898; 47703
之类的行。如果你想将它重定向到某个文件(所有找到的行将在单个输出文件中),你可以将它添加到那个长命令的最后一个回显,如:
for f in *.csv ; do value=`grep -v -e "^*" -e " p; " -e " d; " -e '^\s*$' "$f" | cut -d \; -f 11` ; line=`grep -h -E ' d;' "$f" ; echo "$line;$value" > output.csv ; done
为了可读性,多行相同的代码:
for f in *.csv
do
value=`grep -v -e "^*" -e " p; " -e " d; " -e '^\s*$' "$f" | cut -d \; -f 11`
line=`grep -h -E ' d;' "$f"
echo "$line;$value"
done
这听起来像是 sed
的工作:
parse.sed(GNU sed)
/^ +$/d # Ignore empty lines
/^[ 0-9;.]+$/h # Save first "number-only" line to hold space
/ d; / { # Run block on lines containing ' d; '
G # Copy saved line to pattern space
s/\n.*; ([0-9]+) *; *$/; / # Append the last number on the second line
p # to the first line and print the result
}
parse.sed(便携sed)
# Ignore empty lines
/^ +$/d
# Save first "number-only" line to hold space
/^[ 0-9;.]+$/h
# Run block on lines containing ' d; '
/ d; / {
# Copy saved line to pattern space
G
# Append the last number on the second line
# to the first line and print the result
s/\n.*; ([0-9]+) *; *$/; /
p
}
运行 像这样:
sed -Enf parse.sed infile.csv
输出:
5; 64746; d; 140.898; 477003
请注意,这假定文件中只有一行包含字符组 [ 0-9;.]
。
为了 运行 在所有本地 csv 文件上执行以下操作:
sed -Enf parse.sed *.csv
我有一些 CSV 文件,我想用 grep(或终端中的其他一些函数)解析这些文件以提取一些信息。 它们的形式是:
* Comment 1
* Comment line 2 explaining what the following numbers mean
1000000 ; 3208105 ; 0.18 ; 0.45 ; 0.00015 ; 0.1485 ; 0.03 ; 1 ; 1 ; 5 ; 477003 ;
* Comment 3
* Comment 4 explaining the meaning of the following lines
* Comment 5
0; 706520; p; 30.4983
1; 20859; p; 57.8
2; 192814; p; 111.842
3; 344542; p; 130.543
4; 54605; p; 131.598
5; 64746; d; 140.898
6; 442082; p; 214.11
7; 546701; p; 249.167
8; 298394; p; 305.034
9; 81188; p; 305.034
.......
在每个文件中最多只能有一行第三个字段等于 d
而不是 p
。所以要么有一行包含 d
要么有 none.
我有很多这样的文件,我想做的是从每个文件中提取包含字母 d
的行(如果存在),并在该行之后附加第一个参数的最后一个参数非注释行,在此示例中为 47703
.
到目前为止,我设法分别提取了我需要的行。
有了这个,我可以从我拥有的每个文件中提取包含 d
的每一行:
grep -h -E ' d;' *.csv > output.csv
这样我就可以从文件中准确提取数字 47703
,例如示例中的文件:
grep -v -e "^*" -e " p; " -e " d; " example_file.csv | cut -d \; -f 11
但是我不知道怎么把这两个放在一起。
我想从开头的示例中获得的最终输出是这样的一行:
5; 64746; d; 140.898; 47703
我想为当前目录中的每个 CSV 文件添加这样一行。
有办法吗?
我使用 for 循环来循环所有 .csv 文件,并将 greps 的返回值分配给变量,这些变量在每个循环结束时连接回显:
for f in *.csv ; do value=`grep -v -e "^*" -e " p; " -e " d; " -e '^\s*$' "$f" | cut -d \; -f 11` ; line=`grep -h -E ' d;' "$f" ; echo "$line;$value" ; done
编辑:(我还在第一个 grep 中添加了 -e '^\s*$'
,它在第一个未注释的行上获取包含值的行。之前,它匹配空行)
这只会回显您想要的 5; 64746; d; 140.898; 47703
之类的行。如果你想将它重定向到某个文件(所有找到的行将在单个输出文件中),你可以将它添加到那个长命令的最后一个回显,如:
for f in *.csv ; do value=`grep -v -e "^*" -e " p; " -e " d; " -e '^\s*$' "$f" | cut -d \; -f 11` ; line=`grep -h -E ' d;' "$f" ; echo "$line;$value" > output.csv ; done
为了可读性,多行相同的代码:
for f in *.csv
do
value=`grep -v -e "^*" -e " p; " -e " d; " -e '^\s*$' "$f" | cut -d \; -f 11`
line=`grep -h -E ' d;' "$f"
echo "$line;$value"
done
这听起来像是 sed
的工作:
parse.sed(GNU sed)
/^ +$/d # Ignore empty lines
/^[ 0-9;.]+$/h # Save first "number-only" line to hold space
/ d; / { # Run block on lines containing ' d; '
G # Copy saved line to pattern space
s/\n.*; ([0-9]+) *; *$/; / # Append the last number on the second line
p # to the first line and print the result
}
parse.sed(便携sed)
# Ignore empty lines
/^ +$/d
# Save first "number-only" line to hold space
/^[ 0-9;.]+$/h
# Run block on lines containing ' d; '
/ d; / {
# Copy saved line to pattern space
G
# Append the last number on the second line
# to the first line and print the result
s/\n.*; ([0-9]+) *; *$/; /
p
}
运行 像这样:
sed -Enf parse.sed infile.csv
输出:
5; 64746; d; 140.898; 477003
请注意,这假定文件中只有一行包含字符组 [ 0-9;.]
。
为了 运行 在所有本地 csv 文件上执行以下操作:
sed -Enf parse.sed *.csv