Заменить данные между кавычками в файле

Ваш сетевой адаптер вашей виртуальной машины находится в режиме моста или nat? Проверьте, прослушивает ли ваш сервер порт 22 в конфигурации /etc/ssh/sshd _? Также проверьте, не возникает ли проблема из-за того, что другая виртуальная машина пытается подключиться к этой. Если бы вы могли опубликовать файл конфигурации конфигурации /etc/ssh/sshd _, было бы проще помочь вам устранить неполадки. Пожалуйста, пришлите также информацию об IP-адресе и подсети вашего компьютера с Windows.

4
09.08.2019, 16:56
5 ответов

Попробуйте это:

sed 's/\(\".*\),\(.*\"\)/\1\2/' file
0
27.01.2020, 20:48

Попробуйте напримерawk:

cat oldfile | awk '{ print gensub ("(,\"[0-9]+),([0-9][0-9][0-9]),?([0-9][0-9][0-9])?,?([0-9][0-9][0-9]),?","\\1\\2\\3\\4","g");}' > newfile

Это работает и для больших чисел.

Пояснение:

awk— программируемый фильтр. Команда, указанная здесь в командной строке (между внешними одинарными кавычками "'" ), будет выполняться для каждой строки ввода из вашего файла.

Программа awk выглядит так (другое форматирование):

{
    print gensub ("(,\"[0-9]+),([0-9][0-9][0-9]),?([0-9][0-9][0-9])?,?([0-9][0-9][0-9]),?",
                  "\\1\\2\\3\\4",
                  "g");
}

Встроенная командаawk-gensubзаменяет элементы, указанные в первом аргументе, заменой, указанной во втором. Если третий аргумент представляет собой строку, начинающуюся с "g" или "G", она заменит все вхождения (try до тех пор, пока не будет найдено ).

Что заменено? Первый аргумент — это регулярное выражение (q.v. )в двойных кавычках, вот части:,\затем после [0-9]+что означает цифру 0 -9 повторяется один или несколько раз (постфиксный оператор+)затем ,который является просто символом, затем [0-9][0-9][0-9]и запятая ,, за которой следует вопросительный знак?(теперь вы знаете, что означает первая часть, но постфикс ?новый -цифры запятой можно опустить ). Затем больше групп цифр и запятых, которые можно опустить -, это для больших чисел.

В этом объяснении я до сих пор опускал скобки (и )! Они отмечают те вещи, которые соответствуют выражению, но запоминаются. Во втором аргументе gensubмы ссылаемся на объекты с первого \1по четвертый \4, которым были сопоставлены (числа ), и снова выводим их здесь.

3
27.01.2020, 20:48

Другое awkрешение:

awk -F\" '{
    OFS="\"";
    for ( i = 1; i <= NF; i++ ) {
        if ( i % 2 == 0 ) {
            gsub(/,/, "", $i)
        }
    }
}1' input.csv

Это будет использовать двойную кавычку в качестве разделителя полей и циклически проходить по всем полям. Если номер поля является четным числом (, что не является доказательством дурака -, но в вашем примере это должно означать, что поле существует между кавычками ), оно удалит все запятые из этого поля.1приведет к тому, что awkнапечатает все (с внесенными изменениями ), используя двойную кавычку в качестве разделителя выходных полей.

Используется:

$ cat input.csv
,7/30/2019,7/31/2019,Wed,8/1/2019,FH/FN 30yr & 20yr TBA & Spec,"10,000",8/13/2019,
,7/30/2019,7/31/2019,"100",FH/FN 30yr & 20yr TBA & Spec,"10,000,000",8/13/2019,
,7/30/2019,7/31/2019,"Jack, Mary, and Jane",8/1/2019,"123,456,789,012,345,678","10,000",8/13/2019,
$ awk -F\" '{
>     OFS="\"";
>     for ( i = 1; i <= NF; i++ ) {
>         if ( i % 2 == 0 ) {
>             gsub(/,/, "", $i)
>         }
>     }
> }1' input.csv
,7/30/2019,7/31/2019,Wed,8/1/2019,FH/FN 30yr & 20yr TBA & Spec,"10000",8/13/2019,
,7/30/2019,7/31/2019,"100",FH/FN 30yr & 20yr TBA & Spec,"10000000",8/13/2019,
,7/30/2019,7/31/2019,"Jack Mary and Jane",8/1/2019,"123456789012345678","10000",8/13/2019,

ПРИМЕЧАНИЕ:Это удалит запятые в полях, которые не являются числами. Чтобы правильно прочитать этот файл как csv, вам нужно это сделать. Если по какой-то причине вы хотите сохранить эти запятые, вы можете использовать приведенное ниже решение.


awk -F\" '{
    OFS="\"";
    for ( i = 1; i <= NF; i++ ) {
        if ( i % 2 == 0 && $i ~ /[0-9]/ ) {
            gsub(/,/, "", $i)
        }
    }
}1' input.csv
3
27.01.2020, 20:48

Ваша собственная попытка sed '/\"/,/\"/s/,//'не удалась, потому что указанный вами диапазон адресов фильтрует только диапазон строк, а не диапазон внутри строки.

Этот тип задач является неприятным в стандарте sed. Если речь идет всего об одной запятой, то sed -E 's/("[0-9]*),([0-9]*")/\1 \2/поможет, но для нескольких запятых вам придется зацикливаться, что даст уродливые результаты, такие как

sed -Ee :loop -e 's/("[0-9 ]*),([^"]*")/\1 \2/;tloop'

("[0-9]*)соответствует открывающей двойной кавычке, за которой следует любое количество цифр, и будет называться \1в замене, ([^"]*")соответствует чему угодно после запятой до закрывающей ", поэтому \1 \2то же самое, но с заменой первой запятой.

Теперь команда tпереходит к отметке loop, если была произведена замена. Это повторяется до тех пор, пока не останется запятой, которую нужно заменить.

Это работает даже для случаев с более чем одним числом с любым количеством запятых:,7/30/2019,"99,999,999,999,999",0,1,"10,000","foo, bar"будет преобразовано в,7/30/2019,"99 999 999 999 999" 0 1 "10 000" "foo, bar"

0
27.01.2020, 20:48

Предполагая, что это правильно отформатированный CSV (пример данных выглядит нормально в этом отношении ), мы можем использовать csvformatиз csvkit, чтобы временно изменить разделители полей на какой-либо другой символ, который иначе не присутствует в данных, например @, удалите все запятые и снова измените разделитель полей на значение по умолчанию :

.
$ csvformat -D '@' file.csv | tr -d, | csvformat -d '@'
,7/30/2019,7/31/2019,Wed,8/1/2019,FH/FN 30yr & 20yr TBA & Spec,10000,8/13/2019,

В выходных данных поле, которое мы изменили, не заключено в кавычки, потому что оно больше не нужно.

Очевидно, что «удаление всех запятых» может удалить запятые, которые мы на самом деле не хотим удалять, поэтому мы можем быть немного более избирательным и удалять запятые только в 7-м поле:

$ csvformat -D '@' file.csv | awk -F '@' 'BEGIN { OFS=FS } { gsub(",", "", $7); print }' | csvformat -d '@'
,7/30/2019,7/31/2019,Wed,8/1/2019,FH/FN 30yr & 20yr TBA & Spec,10000,8/13/2019,
4
27.01.2020, 20:48

Теги

Похожие вопросы