Заменить определенное поле из файла пользовательским вводом для каждой строки и сохранить в том же файле

Я печатаю, чтобы написать скрипт, который может читать file_name, delimiter и field_number. После этого для каждой строки возьмите ввод, замените поле (указанное в field_number) и выведите в тот же файл.

Например, если ввод выглядит следующим образом:

Ritesh; М; тысячу девятьсот девяносто два
Шакья;F;1993

Для команды

bash_script.sh test.csv ";" 3

Итерация по каждой строке, если я ввел 1994 для первого и 1995 для второго. Я хочу, чтобы выходные данные были в том же виде, что и в том же файле.

Ritesh; М;1994
Шакья;F;1995

До сих пор мне удалось подняться до этой точки:

#!/usr/bin/env bash
echo "Following is the input needed:";
echo "\$1: FILE_NAME";
echo "\$2: DELIMITER";
echo "\$3: FIELD IN NUMERIC VALUE";

gawk -i inplace -F "$2" '{...}' $1;

Также моя версия gawk не поддерживает -i. Заранее спасибо.

2 ответа

Решение

Ответ на первый вопрос

Если вам нужно только заменить 1992 с 1994 а также 1993 с 1995вам не нужен скрипт, вы можете легко сделать это с помощью sed:

sed "s/;1992/;1994/g" test.csv | sed "s/;1993/;1995/g" 

Выход:

[shell] ➤ sed "s/;1992/;1994/g" test.csv | sed "s/;1993/;1995/g"
Ritesh;M;1994
Shakya;F;1995

Если вам также нужно сохранить вывод, вы можете добавить

sed "s/;1992/;1994/g" test.csv | sed "s/;1993/;1995/g" > temp; mv temp test.scv 

Но если вы хотите использовать скрипт:

#!/bin/bash

if [ -z "${1}" ];then
        echo "Usage: $0 <filename>"
else
        FILENAME=$1
        sed "s/;1992/;1994/g" $FILENAME| sed "s/;1993/;1995/g"
fi

Выход:

[shell] ➤ ./test3.sh
Usage: ./test3.sh <filename>

[shell] ➤ ./test3.sh test.csv
Ritesh;M;1994
Shakya;F;1995

Скрипт обновлен после последнего комментария

#!/bin/bash
if [ -z "${3}" ];then
        echo "Usage: <filename> <delimiter> <field_no>"
else
        FILENAME=$(readlink -f $1)
        DELIMITER=$2
        FIELD_NO=$3
        TEMP_FILE=/tmp/tempFile
        if [ -f $TEMP_FILE ]; then
            rm $TEMP_FILE
        fi
        for line in $(cat $FILENAME)
        do
                oldValue=`echo $line|cut -d$DELIMITER -f$FIELD_NO`
                echo "Enter the value to replace [$oldValue]"
                read newValue
                echo $line | sed "s/${oldValue}/${newValue}/g" >> $TEMP_FILE
        done
fi
mv $TEMP_FILE $FILENAME    

Я прокомментировал команду #mv tempFile $FILENAME потому что это ваш выбор переименовать файл или сохранить новый.

Использование sed - это всегда мой отказ;

#!/bin/bash
FILE=$1
DELIM=$2
FIELD=$3

REPLACEMENT="XXX"
sed "s/[^$DELIM]*/$REPLACEMENT/$FIELD" $FILE

Если это должно быть что-то, рассчитанное по текущему значению, вам нужно зациклить каждую строку и извлечь ее.

#!/bin/bash
FILE=$1
DELIM=$2
FIELD=$3

while read line; do
   value="$(echo $line | cut -d"$DELIM" -f$FIELD)"
   if [ "$value" == "1992" ]; then REPLACEMENT="1994";
   elif [ "$value" == "1993" ]; then REPLACEMENT="1995";
   fi
   echo $line | sed "s/[^$DELIM]*/$REPLACEMENT/$FIELD"
done < $FILE
Другие вопросы по тегам