Многократно отредактируйте единственный файл

Можно всегда использовать LD_PRELOAD обманите к тому, чтобы Linux подражал пути BSD. fddup.c:

#define _GNU_SOURCE
#include <dlfcn.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int whichfd(const char *pathname)
{
  unsigned int fd;
  if (sscanf(pathname, "/dev/fd/%u", &fd) == 1)
    return fd;
  else
    return -1;
}

int open(const char *pathname, int flags, mode_t mode)
{
  static int (*orig)(const char *, int, mode_t) = 0;
  int fd = whichfd(pathname);
  if (fd >= 0)
    return dup(fd);
  else {
    if (!orig)
      orig = dlsym(RTLD_NEXT,"open");
    if (!orig) abort();
    return orig(pathname, flags, mode);
  }
}

FILE *fopen(const char *path, const char *mode)
{
  static FILE *(*orig)(const char *, const char *) = 0;
  int fd = whichfd(path);
  if (fd >= 0)
    return fdopen(dup(fd), mode);
  else {
    if (!orig)
      orig = dlsym(RTLD_NEXT,"fopen");
    if (!orig) abort();
    return orig(path, mode);
  }
}

(Вы, возможно, должны перенестись больше как freopen()).

gcc -Wall -fPIC -shared -o fddup.so fddup.c -ldl

И затем:

socat TCP:localhost:22 'EXEC:env LD_PRELOAD=./ddup.so cat /dev/fd/0,nofork'

Обратите внимание, что Linux и BSD существенно отличаются. Это не так, что Вы не можете открыться /dev/fd/0 когда это - сокет, но это /dev/fd/x символьная ссылка на файл, который открыт на fd x. Вы не можете сделать open() на сокете, который не имел бы смысла. open("/dev/fd/x") нисколько не a dup(x) как в BSD. Похоже на него, когда файл является каналом, но это даже не затем, это - в действительности то же как как открытие именованного канала (можно даже открыть его в другом режиме (чтение по сравнению с записью) для получения другого конца канала).

Оба подхода имеют свои за и против. Это звучит мне, Ваше приложение должно взять fd числа в качестве аргументов, не используют /dev/fd/x который является взломом во-первых так или иначе и например заставил бы Вас тратить впустую fds.

2
22.08.2014, 12:40
4 ответа

С awk :

$ awk 'FNR%2==0{sub(255,1)}1' file
myName_tx_1 VARCHAR(255)
myName_in_1 VARCHAR(1)
myName_tx_2 VARCHAR(255)
myName_in_2 VARCHAR(1)
myName_tx_3 VARCHAR(255)
myName_in_3 VARCHAR(1)
myAddress_tx_1 VARCHAR(255)
myAddress_in_2 VARCHAR(1)

Объяснение

  • FNR% 2 == 0 соответствует только четным строкам.
  • Если строка четная, мы заменяем 255 на 1 , sub (255,1) .
  • 1 - истинное условие, make awk print $ 0 .

Та же логика может использоваться с другими инструментами, такими как perl :

perl -pe 's/255/1/ unless $. % 2' file

С помощью sed вы можете:

sed -e 'n;s/255/1/' file

Обновить

С вашими требованиями к обновлению, мы можем немного изменить решение.

С awk :

awk '/_in_[0-9]/{sub(255,1)}1' file

С sed :

sed -e '/_in_[0-9]/{s/255/1/}' file

С perl :

perl -pe 's/255/1/ if /_in_[0-9]/' file
6
27.01.2020, 21:49

В GNU sed вы можете указать адреса строк в формате first ~ step , чтобы изменять каждую вторую строку, начиная со второй, вы могли бы использовать адрес 2 ~ 2 , например.

$ sed '2~2 s/(255)/(1)/' file
myName_tx_1 VARCHAR(255)
myName_in_1 VARCHAR(1)
myName_tx_2 VARCHAR(255)
myName_in_2 VARCHAR(1)
myName_tx_3 VARCHAR(255)
myName_in_3 VARCHAR(1)
myAddress_tx_1 VARCHAR(255)
myAddress_in_2 VARCHAR(1)
6
27.01.2020, 21:49

Есть

sed '/_in_/ s/255/1/'

, что означает: для совпадения строк /_в__/ искать 255 и заменять на 1.

3
27.01.2020, 21:49
cat oldfile.txt |awk '/_in_[0-9]/{sub(255,1)}1' > newfile.txt
-1
27.01.2020, 21:49

Теги

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