Bash脚本读取一个文件。

时间:2021-07-13 09:09:56

Not sure why the last line does not cut the " from the script:

不知道为什么最后一行没有从脚本中删除:

#!/bin/bash

FILENAME=$1
while read line
do
cut -d '"' -f2
echo $line
done < $FILENAME

$ cat file

"1" test
"2" test
"3" test
"4" test
"5" test

If I run this script with the following command:

如果我使用以下命令运行此脚本:

$ ./test file

2
3
4
5
"1" test

4 个解决方案

#1


6  

The loop executes once.

循环执行一次。

  • It reads "1" test into variable $line.
  • 它将“1”测试读入变量$line。
  • It executes cut -d '"' -f2 which reads lines 2-5 of the file (because that is the standard input at the time) and prints the number.
  • 它执行剪切-d ' ' -f2,它读取文件的第2-5行(因为这是当时的标准输入)并输出数字。
  • It echoes what it read as the first line.
  • 它与它所读的第一行相呼应。

Fix:

解决办法:

cut -d '"' -f2 $FILENAME

If, on the other hand, you want to get the numbers into a variable, you could do this in a variety of ways, including:

另一方面,如果你想把数字变成一个变量,你可以用多种方法来做,包括:

cut -d '"' -f2 $FILENAME |
while read number
do  # What you want
    echo $number
done

or:

或者:

while read line
do
    number=$(echo "$line" | cut -d '"' -f2)
    echo $number
done

#2


2  

Bash can do all the work for you. There's no need for cut:

Bash可以为您完成所有的工作。没有必要削减:

#!/bin/bash

FILENAME=$1
while read -r -a line
do
    echo ${line//\"}
done < "$FILENAME"

That reads the line into an array, then treats the array as a scalar which gives you the first element. Then the brace expansion in the echo strips out the quotation marks.

它将该行读入一个数组,然后将数组视为一个标量,它将为您提供第一个元素。然后在回波中展开的括号去掉了引号。

Or you can let cut do all the work and give Bash a long coffee break:

或者你可以让cut完成所有的工作,并给Bash一个长时间的休息时间:

FILENAME=$1
cut -d '"' -f2 "$FILENAME"

Always quote variables that contain filenames.

总是引用包含文件名的变量。

#3


0  

Jonathan Leffler's given you a simpler method (which will also be more efficient), but in case this is a simplification for something you're going to expand on (where just calling cut won't do what you want), and just to demonstrate the principle anyway, your code would need to be fixed up to feed each line to stdin explicitly as follows:

Jonathan Leffler的给你一个更简单的方法(也将更有效),但如果这是一个简化的东西你要扩展(打电话只是削减不会做你想做的事情),为了演示原理,代码需要固定的每一行给stdin明确如下:

#!/bin/bash

FILENAME=$1
while read line
do
    echo $line | cut -d '"' -f2
done < $FILENAME

#4


0  

like dennis mentioned, there's no need to use external commands

就像dennis提到的,没有必要使用外部命令。

$ while read -r line; do  set -- $line;  echo ${1//\"/}; done<file
1
2
3
4
5

But external commands runs faster if you have very large files.

但是如果有非常大的文件,外部命令会运行得更快。

$ cut -d'"' -f2 file
1
2
3
4
5
$ awk -F'"' '{print $2}' file
1
2
3
4
5
$ sed 's/^"//;s/".*//' file
1
2
3
4
5

#1


6  

The loop executes once.

循环执行一次。

  • It reads "1" test into variable $line.
  • 它将“1”测试读入变量$line。
  • It executes cut -d '"' -f2 which reads lines 2-5 of the file (because that is the standard input at the time) and prints the number.
  • 它执行剪切-d ' ' -f2,它读取文件的第2-5行(因为这是当时的标准输入)并输出数字。
  • It echoes what it read as the first line.
  • 它与它所读的第一行相呼应。

Fix:

解决办法:

cut -d '"' -f2 $FILENAME

If, on the other hand, you want to get the numbers into a variable, you could do this in a variety of ways, including:

另一方面,如果你想把数字变成一个变量,你可以用多种方法来做,包括:

cut -d '"' -f2 $FILENAME |
while read number
do  # What you want
    echo $number
done

or:

或者:

while read line
do
    number=$(echo "$line" | cut -d '"' -f2)
    echo $number
done

#2


2  

Bash can do all the work for you. There's no need for cut:

Bash可以为您完成所有的工作。没有必要削减:

#!/bin/bash

FILENAME=$1
while read -r -a line
do
    echo ${line//\"}
done < "$FILENAME"

That reads the line into an array, then treats the array as a scalar which gives you the first element. Then the brace expansion in the echo strips out the quotation marks.

它将该行读入一个数组,然后将数组视为一个标量,它将为您提供第一个元素。然后在回波中展开的括号去掉了引号。

Or you can let cut do all the work and give Bash a long coffee break:

或者你可以让cut完成所有的工作,并给Bash一个长时间的休息时间:

FILENAME=$1
cut -d '"' -f2 "$FILENAME"

Always quote variables that contain filenames.

总是引用包含文件名的变量。

#3


0  

Jonathan Leffler's given you a simpler method (which will also be more efficient), but in case this is a simplification for something you're going to expand on (where just calling cut won't do what you want), and just to demonstrate the principle anyway, your code would need to be fixed up to feed each line to stdin explicitly as follows:

Jonathan Leffler的给你一个更简单的方法(也将更有效),但如果这是一个简化的东西你要扩展(打电话只是削减不会做你想做的事情),为了演示原理,代码需要固定的每一行给stdin明确如下:

#!/bin/bash

FILENAME=$1
while read line
do
    echo $line | cut -d '"' -f2
done < $FILENAME

#4


0  

like dennis mentioned, there's no need to use external commands

就像dennis提到的,没有必要使用外部命令。

$ while read -r line; do  set -- $line;  echo ${1//\"/}; done<file
1
2
3
4
5

But external commands runs faster if you have very large files.

但是如果有非常大的文件,外部命令会运行得更快。

$ cut -d'"' -f2 file
1
2
3
4
5
$ awk -F'"' '{print $2}' file
1
2
3
4
5
$ sed 's/^"//;s/".*//' file
1
2
3
4
5