从文件中读取行并使用 Bash 以特定格式输出
Read lines from a file and output with specific formatting with Bash
在A.csv中,有
1
2
3
4
我应该如何读取此文件并创建变量 $B
和 $C
以便:
echo $B
echo $C
returns:
1 2 3 4
1,2,3,4
到目前为止我正在尝试:
cat A.csv | while read A;
do
echo $A
done
只有returns
1
2
3
4
B=$(cat A.csv)
echo $B
输出:
1 2 3 4
带引号:
echo "$B"
输出:
1
2
3
4
试试这个:
cat A.csv | while read A;
do
printf "$A"
done
此致!
正如@Cyrus 所说
B=$(cat A.csv)
echo $B
将输出:
1 2 3 4
因为如果变量没有用引号括起来,bash 将不会携带换行符。如果 A.csv
包含任何可能受 bash glob 扩展影响的字符,这是危险的,但如果您只是阅读简单的字符串,应该没问题。
如果您正在读取任何元素中没有空格的简单字符串,您还可以通过使用以下方法获得 $C 所需的结果:
echo $B | tr ' ' ','
这将输出:
1,2,3,4
如果 A.csv
中的行可能包含 bash 特殊字符或空格,那么我们 return 循环。
为什么我把文件读取循环格式化成这样,参考:Looping through the content of a file in Bash?
B=''
C=''
while read -u 7 curr_line; do
if [ "$B$C" == "" ]; then
B="$curr_line"
C="$curr_line"
else
B="$B $curr_line"
C="$C,$curr_line"
fi
done 7<A.csv
echo "$B"
echo "$C"
将使用遍历文件内容的循环根据需要构造两个变量,并应防止不必要的通配和拆分。
假设 bash 4.x,以下是高效、稳健且原生的:
# Read each line of A.csv into a separate element of the array lines
readarray -t lines <A.csv
# Generate a string B with a comma after each item in the array
printf -v B '%s,' "${lines[@]}"
# Prune the last comma from that string
B=${B%,}
# Generate a string C with a space after each item in the array
printf -v B '%s ' "${lines[@]}"
我会将文件读入 bash 数组:
mapfile -t array < A.csv
然后,使用各种连接字符
b="${array[*]}" # space is the default
echo "$b"
c=$( IFS=","; echo "${array[*]}" )
echo "$c"
或者,您可以使用 paste
以指定的分隔符连接所有行:
b=$( paste -d" " -s < A.csv )
c=$( paste -d"," -s < A.csv )
试试这个(更简单的一个):
b=$(tr '\n' ' ' < file)
c=$(tr '\n' ',' < file)
您不必为此阅读文件。确保你 运行 dos2unix file
命令。如果你是运行在windows(删除\r
)。
注意: 会修改文件。因此,请确保您是从原始文件复制的。
在A.csv中,有
1
2
3
4
我应该如何读取此文件并创建变量 $B
和 $C
以便:
echo $B
echo $C
returns:
1 2 3 4
1,2,3,4
到目前为止我正在尝试:
cat A.csv | while read A;
do
echo $A
done
只有returns
1
2
3
4
B=$(cat A.csv)
echo $B
输出:
1 2 3 4
带引号:
echo "$B"
输出:
1 2 3 4
试试这个:
cat A.csv | while read A;
do
printf "$A"
done
此致!
正如@Cyrus 所说
B=$(cat A.csv)
echo $B
将输出:
1 2 3 4
因为如果变量没有用引号括起来,bash 将不会携带换行符。如果 A.csv
包含任何可能受 bash glob 扩展影响的字符,这是危险的,但如果您只是阅读简单的字符串,应该没问题。
如果您正在读取任何元素中没有空格的简单字符串,您还可以通过使用以下方法获得 $C 所需的结果:
echo $B | tr ' ' ','
这将输出:
1,2,3,4
如果 A.csv
中的行可能包含 bash 特殊字符或空格,那么我们 return 循环。
为什么我把文件读取循环格式化成这样,参考:Looping through the content of a file in Bash?
B=''
C=''
while read -u 7 curr_line; do
if [ "$B$C" == "" ]; then
B="$curr_line"
C="$curr_line"
else
B="$B $curr_line"
C="$C,$curr_line"
fi
done 7<A.csv
echo "$B"
echo "$C"
将使用遍历文件内容的循环根据需要构造两个变量,并应防止不必要的通配和拆分。
假设 bash 4.x,以下是高效、稳健且原生的:
# Read each line of A.csv into a separate element of the array lines
readarray -t lines <A.csv
# Generate a string B with a comma after each item in the array
printf -v B '%s,' "${lines[@]}"
# Prune the last comma from that string
B=${B%,}
# Generate a string C with a space after each item in the array
printf -v B '%s ' "${lines[@]}"
我会将文件读入 bash 数组:
mapfile -t array < A.csv
然后,使用各种连接字符
b="${array[*]}" # space is the default
echo "$b"
c=$( IFS=","; echo "${array[*]}" )
echo "$c"
或者,您可以使用 paste
以指定的分隔符连接所有行:
b=$( paste -d" " -s < A.csv )
c=$( paste -d"," -s < A.csv )
试试这个(更简单的一个):
b=$(tr '\n' ' ' < file)
c=$(tr '\n' ',' < file)
您不必为此阅读文件。确保你 运行 dos2unix file
命令。如果你是运行在windows(删除\r
)。
注意: 会修改文件。因此,请确保您是从原始文件复制的。