0
oldfile=test.csv
read -p "Enter File location: "$savelocation1
read -p "Enter File name: " $newfile1

grep "foobar" $oldfile > $savelocation1/$newfile1

awk ' BEGIN {FS=","}
          { 
              printf "%-5s %-10s" \n, $1, $3
          } ' < $savelocation1/$newfile1

grep will create a new file called $newfile that only contains the lines "foobar" from the $oldfile but then when i do an awk to print the 1st and 3rd columns into the $newfile1 the problem with this is that it doesn't write the output of awk to the $newfile1 but it just prints the results to the terminal.

Edit - I used a tempory file to store then output then transfer it to the original file. however this only works for grep and not any awk statement for some reason.

$savelocation1/$oldfile> $savelocation1/tempfile.csv && mv $savelocation1/tempfile.csv $savelocation1/$newfile
2
  • 1
    Your awk command gives me awk: cmd. line:3: ^ backslash not last character on line Commented May 13, 2021 at 12:31
  • Redirect output to a temporary file, then rename the temporary file $newfile. Commented May 13, 2021 at 12:31

2 Answers 2

7

If you use GNU awk:

gawk -i inplace '...' filename      # NOT redirected

If you install the moreutils package

awk '...' filename | sponge filename

Use a temp file (only overwrite the original if the awk process completes successfully)

t=$(mktemp)
awk '...' filename >"$t" && mv "$t" filename

BUT, you don't need separate grep and awk here:

awk -F, -v pattern="foobar" '
    $0 ~ pattern {
        printf "%-5s %-10s\n", $1, $3
    }
' $oldfile > $savelocation1/$newfile1

3
  • 1
    making a temp file makes more sense
    – User10
    Commented May 13, 2021 at 13:14
  • but when i use a "$t" to export the result to the original file, the original file is empty.
    – User10
    Commented May 13, 2021 at 13:29
  • edit your question to show the current state of your code. Commented May 13, 2021 at 17:08
2

Since you're using awk, you don't really need grep.

oldfile=test.csv
read -p "Enter File location: " savelocation1
read -p "Enter File name: " newfile1

awk -F, '/foobar/ {printf "%-5s %-10s\n", $1, $3}' "$oldfile" > "$savelocation1/$newfile1"

BTW, I recommend modifying your script so that it takes both arguments (or even just ONE argument, the new filename) from the command line. This will make testing and debugging your scripts a lot easier as you can use bash's history recall features to enter the same dir & filename without having to type them again every time.

e.g.

# accept directory and filename from command line args
# very primitive.  use getopts to do this properly.
[ -n "$1" ] && d="$1"
[ -n "$2" ] && f="$2"

# if not provided on the command line, ask for them
[ -z "$d" ] && read -p "Enter output file location: " d
[ -z "$f" ] && read -p "Enter output file name: " f

oldfile=test.csv
awk -F, '/foobar/ {printf "%-5s %-10s\n", $1, $3}' "$oldfile" > "$d/$f"

then you can run it as:

./myscript.sh somedir somefile.csv

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .