2017-09-25 114 views
1

在A.csv,有读线,猛砸

1 
2 
3 
4 

我应该怎样阅读本文件并创建变量$B$C使:

echo $B 
echo $C 

回报:

1 2 3 4 
1,2,3,4 

到目前为止,我想:

cat A.csv | while read A; 

do 

echo $A 

done 

它只返回

1 
2 
3 
4 
+0

这里有什么“将一个while循环传入变量”? –

回答

1

正如@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特殊字符或空格,则我们返回到循环。

为什么我格式化文件读取循环,因为我有,请参阅: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" 

将建设两个变量,你的愿望使用遍历文件内容,并应防止防止意外通配和分裂。

1
B=$(cat A.csv) 
echo $B 

输出:

 
1 2 3 4 

,随着行情:

echo "$B" 

输出:

 
1 
2 
3 
4 
+0

适用于OP的当前输入,但是如果其文件中的某一行有*号(或带有空格的行),我预计它们的输出可能会令人惊讶。 –

+0

@CharlesDuffy:你可能是对的。 – Cyrus

0

试试这个:

cat A.csv | while read A; 

do 

printf "$A" 

done 

商祺!

+1

Eh?在这种用法中不会有任何换行符,并且如果它包含格式转义符,它也会打乱您的输出。也许你想要'printf'%s'“$ A”',在每个之后打印一个空格,然后在'printf'\ n'后面打印? –

+0

而'cat'只不过是开销而已 - 在'done'之后使用'

2

假设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[@]}" 
1

我将文件读入到一个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) 
+0

'mapfile'和'readarray'是同义词,只能在版本> 4.0中使用,'paste'解决方案整齐且兼容3.x! –

0

试试这个(较简单的):

b=$(tr '\n' ' ' < file) 
c=$(tr '\n' ',' < file) 

您不必读取文件为。确保你运行了dos2unix file命令。如果您正在窗口中运行(要删除\r)。

说明:它会修改文件。所以,请确保您从原始文件复制。